<template>
  <div class="container">
    <div class="content">
      <!-- <div class="panel code-panel">
        <div class="code-container" id="ncCodeContainer"></div>
        <div>
        </div>
        <div class="stats">
          <div class="stat">
            <div class="stat-title">代码行数</div>
            <div class="stat-value" id="lineCount">0</div>
          </div>
          <div class="stat">
            <div class="stat-title">路径点数</div>
            <div class="stat-value" id="pointCount">0</div>
          </div>
          <div class="stat">
            <div class="stat-title">移动指令</div>
            <div class="stat-value" id="moveCount">0</div>
          </div>
          <div class="stat">
            <div class="stat-title">螺旋指令</div>
            <div class="stat-value" id="spiralCount">0</div>
          </div>
        </div>
      </div> -->
      <div class="panel visualization-panel">
        <div id="visualization" ref="clear"></div>
        <div class="legend">
          <div class="legend-item">
            <div class="legend-color g00"></div>
            <div>G00 - 快速移动</div>
          </div>
          <div class="legend-item">
            <div class="legend-color g01"></div>
            <div>G01 - 直线进给</div>
          </div>
          <div class="legend-item">
            <div class="legend-color g02"></div>
            <div>G02 - 顺时针圆弧</div>
          </div>
          <div class="legend-item">
            <div class="legend-color g03"></div>
            <div>G03 - 逆时针圆弧</div>
          </div>
          <div class="legend-item">
            <div class="legend-color spiral"></div>
            <div>螺旋插补</div>
          </div>
          <div class="legend-item">
            <div class="legend-color helical"></div>
            <div>螺旋下刀</div>
          </div>
          <div class="legend-item">
            <div class="legend-color g28"></div>
            <div>G28 - 回零操作</div>
          </div>
          <div class="legend-item">
            <div class="legend-color anim"></div>
            <div>动画点</div>
          </div>
        </div>
        <div class="speed-control">
            <span style="color: aliceblue; margin: 20px;">动画速度: </span>
            <el-slider 
              v-model="animationSpeed" 
              :min="0.1" 
              :max="1" 
              :step="0.1" 
              show-input 
              size="small"
              style="width: 400px; margin: 20px;"
            />
          </div>
        <div class="controls">
          <el-button type="primary" round @click="resetView">重置视图</el-button>
          <el-button type="primary" round @click="togglePoints">显示/隐藏路径点</el-button>
          <el-button type="primary" round @click="toggleAxis">显示/隐藏坐标轴</el-button>
          <el-button type="primary" round @click="playPathAnimation">播放加工动画</el-button>
        </div>
      </div>
    </div>
    <!-- <div class="depth-indicator">
      <div class="depth-title">当前加工深度</div>
      <div class="depth-value" id="depthValue">0.00 mm</div>
    </div> -->
  </div>

  <div class="tooltip" id="tooltip" style="display: none;">
    <h3>路径点详细信息</h3>
    <p>X: <span class="value" id="tooltipX">0.000</span> mm</p>
    <p>Y: <span class="value" id="tooltipY">0.000</span> mm</p>
    <p>Z: <span class="value" id="tooltipZ">0.000</span> mm</p>
    <p>指令类型: <span class="value" id="tooltipType">G00</span></p>
    <p>路径点序号: <span class="value" id="tooltipIndex">0</span></p>
    <p>加工深度: <span class="value" id="tooltipDepth">0.00</span> mm</p>
  </div>
</template>

<script setup lang="ts">
import * as THREE from "three";
import { onMounted, ref, reactive, onUnmounted } from "vue";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import * as TWEEN from "three/examples/jsm/libs/tween.module.js";
import { ElSlider } from 'element-plus'; // 导入滑块组件

let clear = ref();
let clearWindow = reactive({width: 1000,height: 600});
// 设置Three.js场景
const scene = new (THREE as any).Scene();
scene.background = new (THREE as any).Color(0xeeeeee);

// 添加坐标轴辅助
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);

// 创建渲染器
const render = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true,
    logarithmicDepthBuffer: true,
});
render.setSize(clearWindow.width, clearWindow.height);
render.setPixelRatio(window.devicePixelRatio);
render.setClearColor(0xffffff, 1);

// 创建相机
let cameraInfo = {
    position: {
        x: -200,
        y: 100,
        z: 200,
    },
};
const camera = new (THREE as any).PerspectiveCamera(45, clearWindow.width / clearWindow.height, 0.1, 1000);
const bestLength = 30;
camera.position.x = cameraInfo.position.x;
camera.position.y = cameraInfo.position.y;
camera.position.z = cameraInfo.position.z;
camera.lookAt(0, 0, 0);

// 轨道滑动器
const controls = new OrbitControls(camera, render.domElement); //轨道滑动器
controls.enableDamping = true;  // 设置带阻尼的惯性
controls.dampingFactor = 0.1; // 设置阻尼系数
controls.rotateSpeed = 0.2; // 旋转速度


const createLight = (x: number, y: number, z: number) => {
  const color = 0xffffff; //  灯光颜色
  const intensity = 1; // 灯光强度
  const light = new (THREE as any).DirectionalLight(color, intensity);
  light.position.set(x, y, z);
  light.target.position.set(0, 0, 0);
  return light;
};
const lights = [
    createLight(bestLength, bestLength, -bestLength),
    createLight(-bestLength, bestLength, -bestLength),
    createLight(-bestLength, bestLength, bestLength),
    createLight(-bestLength, -bestLength, bestLength),
    createLight(bestLength, -bestLength, -bestLength),
    createLight(-bestLength, -bestLength, -bestLength),
    createLight(-bestLength, -bestLength, bestLength),
    createLight(bestLength, -bestLength, bestLength),
];
lights.forEach((light) => scene.add(light));
lights.forEach((light) => scene.add(light.target));

// 渲染函数
function animate() {
    controls.update();
    requestAnimationFrame(animate);
    render.render(scene, camera);
    TWEEN.update();
}
//////////////////////////////////////////////////////////////////////

// NC代码内容
const ncCode = `
O0001
N1 G21
N2 (10MM CRB 4FL 22 LOC)
N3 G91 G28 X0 Y0 Z0
N4 T01 M06
N5 S12000 M03

N6 ( ��2 )
N7 G90 G54 G00 X-14.5 Y0
N8 G43 Z4.5 H01 M08
N9 G17 G03 X-11.996 Y-4.033 Z4.328 I4.5 J0 F978.395
N10 X-5.5 Y0 Z4.015 I1.996 J4.033
N11 X-10. Y4.5 Z3.773 I-4.5 J0
N12 X-14.5 Y0 Z3.53 I0 J-4.5
N13 X-11.996 Y-4.033 Z3.358 I4.5 J0
N14 X-5.5 Y0 Z3.045 I1.996 J4.033
N15 X-10. Y4.5 Z2.803 I-4.5 J0
N16 X-14.5 Y0 Z2.56 I0 J-4.5
N17 X-11.996 Y-4.033 Z2.388 I4.5 J0
N18 X-5.5 Y0 Z2.075 I1.996 J4.033
N19 X-10. Y4.5 Z1.833 I-4.5 J0
N20 X-14.5 Y0 Z1.59 I0 J-4.5
N21 X-11.996 Y-4.033 Z1.418 I4.5 J0
N22 X-5.5 Y0 Z1.105 I1.996 J4.033
N23 X-10. Y4.5 Z.863 I-4.5 J0
N24 X-14.5 Y0 Z.62 I0 J-4.5
N25 X-11.996 Y-4.033 Z.448 I4.5 J0
N26 X-5.5 Y0 Z.135 I1.996 J4.033
N27 X-10. Y4.5 Z-.107 I-4.5 J0
N28 X-14.5 Y0 Z-.35 I0 J-4.5
N29 X-11.996 Y-4.033 Z-.522 I4.5 J0
N30 X-5.5 Y0 Z-.835 I1.996 J4.033
N31 X-10. Y4.5 Z-1.077 I-4.5 J0
N32 X-14.5 Y0 Z-1.32 I0 J-4.5
N33 X-11.996 Y-4.033 Z-1.492 I4.5 J0
N34 X-5.5 Y0 Z-1.805 I1.996 J4.033
N35 X-10. Y4.5 Z-2.047 I-4.5 J0
N36 X-14.5 Y0 Z-2.29 I0 J-4.5
N37 X-11.996 Y-4.033 Z-2.462 I4.5 J0
N38 X-5.5 Y0 Z-2.775 I1.996 J4.033
N39 X-10. Y4.5 Z-3.018 I-4.5 J0
N40 X-14.5 Y0 Z-3.26 I0 J-4.5
N41 X-11.996 Y-4.033 Z-3.432 I4.5 J0
N42 X-5.5 Y0 Z-3.745 I1.996 J4.033
N43 X-10. Y4.5 Z-3.988 I-4.5 J0
N44 X-14.5 Y0 Z-4.23 I0 J-4.5
N45 X-11.996 Y-4.033 Z-4.402 I4.5 J0
N46 X-5.5 Y0 Z-4.715 I1.996 J4.033
N47 X-10. Y4.5 Z-4.957 I-4.5 J0
N48 X-14.5 Y0 Z-5.2 I0 J-4.5
N49 X-11.996 Y-4.033 Z-5.372 I4.5 J0
N50 X-5.5 Y0 Z-5.685 I1.996 J4.033
N51 X-10. Y4.5 Z-5.927 I-4.5 J0
N52 X-14.5 Y0 Z-6.17 I0 J-4.5
N53 X-11.996 Y-4.033 Z-6.342 I4.5 J0
N54 X-5.5 Y0 Z-6.655 I1.996 J4.033
N55 X-10. Y4.5 Z-6.897 I-4.5 J0
N56 X-14.5 Y0 Z-7.14 I0 J-4.5
N57 X-11.996 Y-4.033 Z-7.312 I4.5 J0
N58 X-5.5 Y0 Z-7.625 I1.996 J4.033
N59 X-10. Y4.5 Z-7.867 I-4.5 J0
N60 X-14.5 Y0 Z-8.11 I0 J-4.5
N61 X-11.996 Y-4.033 Z-8.282 I4.5 J0
N62 X-5.5 Y0 Z-8.595 I1.996 J4.033 F1956.789
N63 X-10. Y4.5 Z-8.837 I-4.5 J0
N64 X-14.5 Y0 Z-9.08 I0 J-4.5
N65 X-11.996 Y-4.033 Z-9.252 I4.5 J0
N66 X-5.5 Y0 Z-9.565 I1.996 J4.033
N67 X-10. Y4.5 Z-9.807 I-4.5 J0
N68 X-14.5 Y0 Z-10.05 I0 J-4.5
N69 X-11.996 Y-4.033 Z-10.222 I4.5 J0
N70 X-5.5 Y0 Z-10.535 I1.996 J4.033
N71 X-10. Y4.5 Z-10.777 I-4.5 J0
N72 X-14.5 Y0 Z-11.02 I0 J-4.5
N73 X-11.996 Y-4.033 Z-11.192 I4.5 J0
N74 X-5.5 Y0 Z-11.505 I1.996 J4.033
N75 X-10. Y4.5 Z-11.747 I-4.5 J0
N76 X-14.5 Y0 Z-11.99 I0 J-4.5
N77 X-11.996 Y-4.033 Z-12.162 I4.5 J0
N78 X-5.5 Y0 Z-12.475 I1.996 J4.033
N79 X-10. Y4.5 Z-12.717 I-4.5 J0
N80 X-14.5 Y0 Z-12.96 I0 J-4.5
N81 X-11.996 Y-4.033 Z-13.132 I4.5 J0
N82 X-5.5 Y0 Z-13.445 I1.996 J4.033
N83 X-10. Y4.5 Z-13.687 I-4.5 J0
N84 X-14.5 Y0 Z-13.93 I0 J-4.5
N85 X-11.996 Y-4.033 Z-14.102 I4.5 J0
N86 X-5.5 Y0 Z-14.415 I1.996 J4.033
N87 X-10. Y4.5 Z-14.657 I-4.5 J0
N88 X-14.5 Y0 Z-14.9 I0 J-4.5
N89 X-11.996 Y-4.033 I4.5 J0
N90 X-5.5 Y0 I1.996 J4.033
N91 X-10. Y4.5 I-4.5 J0
N92 X-14.5 Y0 I0 J-4.5
N93 X-9.918 Y-4.733 I4.583 J-.148 F3952.148
N94 X-5.044 Y0 I0 J4.876 F4079.027
N95 X-10.083 Y5.189 I-5.039 J.148 F4147.925
N96 X-15.413 Y0 I0 J-5.332 F4263.678
N97 X-9.917 Y-5.645 I5.495 J-.147 F4326.699
N98 X-4.131 Y0 I0 J5.788 F4432.728
N99 X-10.083 Y6.101 I-5.952 J.147 F4490.59
N100 X-16.325 Y0 I0 J-6.244 F4588.073
N101 X-9.917 Y-6.557 I6.408 J-.147 F4641.381
N102 X-3.218 Y0 I0 J6.7 F4731.312
N103 X-10.083 Y7.013 I-6.864 J.147 F4780.582
N104 X-17.238 Y0 I0 J-7.156 F4863.806
N105 X-9.917 Y-7.469 I7.321 J-.147 F4909.479
N106 X-2.306 Y0 I0 J7.613 F4986.719
N107 X-10.083 Y7.925 I-7.777 J.147 F5029.174
N108 X-18.15 Y0 I0 J-8.069 F5101.054
N109 X-9.917 Y-8.381 I8.233 J-.147 F5140.619
N110 X-1.393 Y0 I0 J8.525 F5207.678
N111 X-10.083 Y8.837 I-8.69 J.147 F5244.638
N112 X-19.063 Y0 I0 J-8.981 F5307.345
N113 X-9.917 Y-9.294 I9.146 J-.147 F5341.949
N114 X-.481 Y0 I0 J9.438 F5400.714
N115 X-3.275 Y6.9 I-9.557 J.146 F5424.399
N116 X-10.171 Y9.749 I-6.871 J-6.862 F5453.753
N117 X-19.749 Y-.171 I.171 J-9.749 F5461.322
N118 X-9.829 Y-9.749 I9.749 J.171
N119 X-.25 Y.086 I-.171 J9.749
N120 X-9.346 Y9.728 I-9.75 J-.086
N121 X-10. Y9.75 I-.654 J-9.728 F4914.44
N122 G01 X-12.41
N123 G03 X-19.75 Y2.41 I0 J-7.34
N124 G01 Y.171 F8262.
N125 G03 X-17.5 Y-2.079 Z-13.977 I2.25 J0
N126 G01 X-13.83 Y2.711 Z-12.4 F16500.
N127 X-10.16 Y7.5 Z-13.977
N128 G03 X-12.41 Y9.75 Z-14.9 I-2.25 J0 F4131.
N129 G01 X-14.276
N130 X-14.817 F2051.506
N131 G03 X-17.292 Y9.084 I0 J-4.933
N132 X-19.75 Y4.817 I2.475 J-4.267 F4103.013
N133 G01 Y2.41 F8262.
N134 G03 X-15.464 Y1.451 Z-12.965 I2.25 J0
N135 G01 X-14.865 Y3.124 Z-12.4 F16500.
N136 X-13.33 Y7.405 Z-13.848
N137 G03 X-14.817 Y9.75 Z-14.9 I-1.488 J.701 F8262.
N138 G01 X-16.023
N139 G03 X-19.75 Y6.023 I0 J-3.727 F3528.188
N140 G01 Y4.817 F8262.
N141 G03 X-16.674 Y4.009 Z-12.965 I1.644 J0
N142 G01 X-16.16 Y5.163 Z-12.4 F16500.
N143 X-14.942 Y7.897 Z-13.741
N144 G03 X-16.023 Y9.75 Z-14.9 I-1.082 J.61 F8262.
N145 G01 X-17.08
N146 X-17.221 F2775.401
N147 G03 X-19.75 Y7.221 I0 J-2.529
N148 G01 Y6.023 F8262.
N149 G03 X-17.373 Y5.517 Z-12.849 I1.242 J0
N150 G01 X-17.159 Y6.225 Z-12.4 F16500.
N151 X-16.451 Y8.563 Z-13.882
N152 G03 X-17.221 Y9.75 Z-14.9 I-.77 J.344 F8262.
N153 G01 X-17.97
N154 X-18.433 F1722.004
N155 G03 X-19.75 Y8.433 I0 J-1.317
N156 G01 Y7.221 F8262.
N157 G03 X-19.001 Y6.383 Z-13.767 I.843 J0
N158 X-18.085 Y7.035 Z-12.634 I.094 J.838
N159 G01 X-18.075 Y7.288 Z-12.4 F16500.
N160 X-18.005 Y9.214 Z-14.175
N161 G03 X-18.433 Y9.75 Z-14.9 I-.428 J.097 F8262.
N162 G01 X-18.844
N163 X-19.25 F1652.4
N164 G03 X-19.75 Y9.25 I0 J-.5
N165 G01 Y.59 F8262.
N166 Y-2.41 F4914.44
N167 G03 X-12.41 Y-9.75 I7.34 J0
N168 G01 X-10.171 F8262.
N169 G03 X-7.921 Y-7.5 Z-13.977 I0 J2.25
N170 G01 X-12.711 Y-3.83 Z-12.4 F16500.
N171 X-17.5 Y-.16 Z-13.977
N172 G03 X-19.75 Y-2.41 Z-14.9 I0 J-2.25 F4131.
N173 G01 Y-4.276
N174 Y-4.817 F2051.506
N175 G03 X-19.084 Y-7.292 I4.933 J0
N176 X-14.817 Y-9.75 I4.267 J2.475 F4103.013
N177 G01 X-12.41 F8262.
N178 G03 X-11.451 Y-5.464 Z-12.965 I0 J2.25
N179 G01 X-13.124 Y-4.865 Z-12.4 F16500.
N180 X-17.405 Y-3.33 Z-13.848
N181 G03 X-19.75 Y-4.817 Z-14.9 I-.701 J-1.488 F8262.
N182 G01 Y-6.023
N183 G03 X-16.023 Y-9.75 I3.727 J0 F3528.188
N184 G01 X-14.817 F8262.
N185 G03 X-14.009 Y-6.674 Z-12.965 I0 J1.644
N186 G01 X-15.163 Y-6.16 Z-12.4 F16500.
N187 X-17.897 Y-4.942 Z-13.741
N188 G03 X-19.75 Y-6.023 Z-14.9 I-.61 J-1.082 F8262.
N189 G01 Y-7.08
N190 Y-7.221 F2775.401
N191 G03 X-17.221 Y-9.75 I2.529 J0
N192 G01 X-16.023 F8262.
N193 G03 X-15.517 Y-7.373 Z-12.849 I0 J1.242
N194 G01 X-16.225 Y-7.159 Z-12.4 F16500.
N195 X-18.563 Y-6.451 Z-13.882
N196 G03 X-19.75 Y-7.221 Z-14.9 I-.344 J-.77 F8262.
N197 G01 Y-7.97
N198 Y-8.433 F1722.004
N199 G03 X-18.433 Y-9.75 I1.317 J0
N200 G01 X-17.221 F8262.
N201 G03 X-16.383 Y-9.001 Z-13.767 I0 J.843
N202 X-17.035 Y-8.085 Z-12.634 I-.838 J.094
N203 G01 X-17.288 Y-8.075 Z-12.4 F16500.
N204 X-19.214 Y-8.005 Z-14.175
N205 G03 X-19.75 Y-8.433 Z-14.9 I-.097 J-.428 F8262.
N206 G01 Y-8.844
N207 Y-9.25 F1652.4
N208 G03 X-19.25 Y-9.75 I.5 J0
N209 G01 X-12.004 F8262.
N210 X-9.004 F5461.322
N211 G03 X.746 Y0 I0 J9.75
N212 X-9.004 Y9.75 I-9.75 J0
N213 G01 X-9.829 F8262.
N214 G03 X-12.079 Y7.5 Z-14.1 I0 J-2.25
N215 G01 X-11.666 Y0 Z-12.4 F16500.
N216 X-11.254 Y-7.5 Z-14.1
N217 G03 X-9.004 Y-9.75 Z-14.9 I2.25 J0 F4131.
N218 G01 X-8.02
N219 G03 X-4.117 Y-8.934 I0 J9.75 F2730.661
N220 X-8.02 Y9.75 I-3.904 J8.934 F5461.322
N221 G01 X-9.004 F8262.
N222 G03 X-11.249 Y7.353 Z-14.067 I0 J-2.25
N223 G01 X-10.767 Y0 Z-12.4 F16500.
N224 X-10.265 Y-7.647 Z-14.134
N225 G03 X-8.02 Y-9.75 Z-14.9 I2.245 J.147 F8262.
N226 G01 X-7.017
N227 G03 X2.733 Y0 I0 J9.75 F5461.322
N228 X-7.017 Y9.75 I-9.75 J0
N229 G01 X-8.02 F8262.
N230 G03 X-10.265 Y7.35 Z-14.066 I0 J-2.25
N231 G01 X-9.774 Y0 Z-12.4 F16500.
N232 X-9.262 Y-7.65 Z-14.134
N233 G03 X-7.017 Y-9.75 Z-14.9 I2.245 J.15 F8262.
N234 G01 X-6.004
N235 G03 X3.746 Y0 I0 J9.75 F5461.322
N236 X-6.004 Y9.75 I-9.75 J0
N237 G01 X-7.017 F8262.
N238 G03 X-9.262 Y7.348 Z-14.066 I0 J-2.25
N239 G01 X-8.765 Y0 Z-12.4 F16500.
N240 X-8.248 Y-7.652 Z-14.135
N241 G03 X-6.004 Y-9.75 Z-14.9 I2.245 J.152 F8262.
N242 G01 X-5.019
N243 G03 X4.731 Y0 I0 J9.75 F5461.322
N244 X-5.019 Y9.75 I-9.75 J0
N245 G01 X-6.004 F8262.
N246 G03 X-8.249 Y7.353 Z-14.067 I0 J-2.25
N247 G01 X-7.766 Y0 Z-12.4 F16500.
N248 X-7.264 Y-7.647 Z-14.134
N249 G03 X-5.019 Y-9.75 Z-14.9 I2.245 J.147 F8262.
N250 G01 X-4.007
N251 G03 X5.743 Y0 I0 J9.75 F5461.322
N252 X-4.007 Y9.75 I-9.75 J0
N253 G01 X-5.019 F8262.
N254 G03 X-7.264 Y7.349 Z-14.066 I0 J-2.25
N255 G01 X-6.768 Y0 Z-12.4 F16500.
N256 X-6.252 Y-7.651 Z-14.135
N257 G03 X-4.007 Y-9.75 Z-14.9 I2.245 J.151 F8262.
N258 G01 X-3.008
N259 G03 X6.742 Y0 I0 J9.75 F5461.322
N260 X-3.008 Y9.75 I-9.75 J0
N261 G01 X-4.007 F8262.
N262 G03 X-6.252 Y7.351 Z-14.067 I0 J-2.25
N263 G01 X-5.763 Y0 Z-12.4 F16500.
N264 X-5.253 Y-7.649 Z-14.134
N265 G03 X-3.008 Y-9.75 Z-14.9 I2.245 J.149 F8262.
N266 G01 X-2.005
N267 G03 X7.745 Y0 I0 J9.75 F5461.322
N268 X-2.005 Y9.75 I-9.75 J0
N269 G01 X-3.008 F8262.
N270 G03 X-5.253 Y7.35 Z-14.066 I0 J-2.25
N271 G01 X-4.762 Y0 Z-12.4 F16500.
N272 X-4.25 Y-7.65 Z-14.134
N273 G03 X-2.005 Y-9.75 Z-14.9 I2.245 J.15 F8262.
N274 G01 X-1.008
N275 G03 X8.742 Y0 I0 J9.75 F5461.322
N276 X-1.008 Y9.75 I-9.75 J0
N277 G01 X-2.005 F8262.
N278 G03 X-4.25 Y7.351 Z-14.067 I0 J-2.25
N279 G01 X-3.761 Y0 Z-12.4 F16500.
N280 X-3.253 Y-7.649 Z-14.134
N281 G03 X-1.008 Y-9.75 Z-14.9 I2.245 J.149 F8262.
N282 G01 X-.009
N283 G03 X9.741 Y0 I0 J9.75 F5461.322
N284 X-.009 Y9.75 I-9.75 J0
N285 G01 X-1.008 F8262.
N286 G03 X-3.253 Y7.35 Z-14.067 I0 J-2.25
N287 G01 X-2.763 Y0 Z-12.4 F16500.
N288 X-2.254 Y-7.65 Z-14.134
N289 G03 X-.009 Y-9.75 Z-14.9 I2.245 J.15 F8262.
N290 G01 X.988
N291 G03 X10.738 Y0 I0 J9.75 F5461.322
N292 X.988 Y9.75 I-9.75 J0
N293 G01 X-.009 F8262.
N294 G03 X-2.254 Y7.351 Z-14.067 I0 J-2.25
N295 G01 X-1.765 Y0 Z-12.4 F16500.
N296 X-1.257 Y-7.649 Z-14.134
N297 G03 X.988 Y-9.75 Z-14.9 I2.245 J.149 F8262.
N298 G01 X1.992
N299 G03 X11.742 Y0 I0 J9.75 F5461.322
N300 X1.992 Y9.75 I-9.75 J0
N301 G01 X.988 F8262.
N302 G03 X-1.257 Y7.35 Z-14.066 I0 J-2.25
N303 G01 X-.765 Y0 Z-12.4 F16500.
N304 X-.253 Y-7.65 Z-14.134
N305 G03 X1.992 Y-9.75 Z-14.9 I2.245 J.15 F8262.
N306 G01 X2.977
N307 G03 X12.727 Y0 I0 J9.75 F5461.322
N308 X2.977 Y9.75 I-9.75 J0
N309 G01 X1.992 F8262.
N310 G03 X-.253 Y7.353 Z-14.067 I0 J-2.25
N311 G01 X.23 Y0 Z-12.4 F16500.
N312 X.732 Y-7.647 Z-14.134
N313 G03 X2.977 Y-9.75 Z-14.9 I2.245 J.147 F8262.
N314 G01 X3.978
N315 G03 X13.728 Y0 I0 J9.75 F5461.322
N316 X3.978 Y9.75 I-9.75 J0
N317 G01 X2.977 F8262.
N318 G03 X.732 Y7.35 Z-14.067 I0 J-2.25
N319 G01 X1.223 Y0 Z-12.4 F16500.
N320 X1.733 Y-7.65 Z-14.134
N321 G03 X3.978 Y-9.75 Z-14.9 I2.245 J.15 F8262.
N322 G01 X4.978
N323 G03 X14.728 Y0 I0 J9.75 F5461.322
N324 X4.978 Y9.75 I-9.75 J0
N325 G01 X3.978 F8262.
N326 G03 X1.733 Y7.35 Z-14.067 I0 J-2.25
N327 G01 X2.223 Y0 Z-12.4 F16500.
N328 X2.733 Y-7.65 Z-14.134
N329 G03 X4.978 Y-9.75 Z-14.9 I2.245 J.15 F8262.
N330 G01 X5.979
N331 G03 X15.729 Y0 I0 J9.75 F5461.322
N332 X5.979 Y9.75 I-9.75 J0
N333 G01 X4.978 F8262.
N334 G03 X2.733 Y7.35 Z-14.067 I0 J-2.25
N335 G01 X3.223 Y0 Z-12.4 F16500.
N336 X3.734 Y-7.65 Z-14.134
N337 G03 X5.979 Y-9.75 Z-14.9 I2.245 J.15 F8262.
N338 G01 X6.968
N339 G03 X16.718 Y0 I0 J9.75 F5461.322
N340 X6.968 Y9.75 I-9.75 J0
N341 G01 X5.979 F8262.
N342 G03 X3.733 Y7.352 Z-14.067 I0 J-2.25
N343 G01 X4.218 Y0 Z-12.4 F16500.
N344 X4.723 Y-7.648 Z-14.134
N345 G03 X6.968 Y-9.75 Z-14.9 I2.245 J.148 F8262.
N346 G01 X7.975
N347 G03 X17.725 Y0 I0 J9.75 F5461.322
N348 X7.975 Y9.75 I-9.75 J0
N349 G01 X6.968 F8262.
N350 G03 X4.723 Y7.349 Z-14.066 I0 J-2.25
N351 G01 X5.216 Y0 Z-12.4 F16500.
N352 X5.73 Y-7.651 Z-14.135
N353 G03 X7.975 Y-9.75 Z-14.9 I2.245 J.151 F8262.
N354 G01 X8.972
N355 G03 X18.722 Y0 I0 J9.75 F5461.322
N356 X8.972 Y9.75 I-9.75 J0
N357 G01 X7.975 F8262.
N358 G03 X5.73 Y7.351 Z-14.067 I0 J-2.25
N359 G01 X6.218 Y0 Z-12.4 F16500.
N360 X6.727 Y-7.649 Z-14.134
N361 G03 X8.972 Y-9.75 Z-14.9 I2.245 J.149 F8262.
N362 G01 X10.
N363 G03 X19.75 Y0 I0 J9.75 F5461.322
N364 X10. Y9.75 I-9.75 J0
N365 G01 X8.972 F8262.
N366 G03 X6.727 Y7.346 Z-14.066 I0 J-2.25
N367 G01 X7.231 Y0 Z-12.4 F16500.
N368 X7.755 Y-7.654 Z-14.135
N369 G03 X10. Y-9.75 Z-14.9 I2.245 J.154 F8262.
N370 G01 X12.339
N371 X12.41 F4914.44
N372 G03 X19.75 Y-2.41 I0 J7.34
N373 G01 Y0 F8262.
N374 G03 X15.638 Y1.264 Z-13.444 I-2.25 J0
N375 G01 X13.332 Y-2.134 Z-12.4 F16500.
N376 X10.548 Y-6.236 Z-13.66
N377 G03 X12.41 Y-9.75 Z-14.9 I1.862 J-1.264 F8262.
N378 G01 X14.276
N379 X14.817 F4103.013
N380 G03 X19.75 Y-4.817 I0 J4.933
N381 G01 Y-2.41 F8262.
N382 G03 X15.464 Y-1.451 Z-12.965 I-2.25 J0
N383 G01 X14.865 Y-3.124 Z-12.4 F16500.
N384 X13.33 Y-7.405 Z-13.848
N385 G03 X14.817 Y-9.75 Z-14.9 I1.488 J-.701 F8262.
N386 G01 X16.023
N387 G03 X19.75 Y-6.023 I0 J3.727 F3528.188
N388 G01 Y-4.817 F8262.
N389 G03 X16.674 Y-4.009 Z-12.965 I-1.644 J0
N390 G01 X16.16 Y-5.163 Z-12.4 F16500.
N391 X14.942 Y-7.897 Z-13.741
N392 G03 X16.023 Y-9.75 Z-14.9 I1.082 J-.61 F8262.
N393 G01 X17.08
N394 X17.221 F2775.401
N395 G03 X19.75 Y-7.221 I0 J2.529
N396 G01 Y-6.023 F8262.
N397 G03 X17.373 Y-5.517 Z-12.849 I-1.242 J0
N398 G01 X17.159 Y-6.225 Z-12.4 F16500.
N399 X16.451 Y-8.563 Z-13.882
N400 G03 X17.221 Y-9.75 Z-14.9 I.77 J-.344 F8262.
N401 G01 X17.97
N402 X18.433 F1722.004
N403 G03 X19.75 Y-8.433 I0 J1.317
N404 G01 Y-7.221 F8262.
N405 G03 X19.001 Y-6.383 Z-13.767 I-.843 J0
N406 X18.085 Y-7.035 Z-12.634 I-.094 J-.838
N407 G01 X18.075 Y-7.288 Z-12.4 F16500.
N408 X18.005 Y-9.214 Z-14.175
N409 G03 X18.433 Y-9.75 Z-14.9 I.428 J-.097 F8262.
N410 G01 X18.844
N411 X19.25 F1652.4
N412 G03 X19.75 Y-9.25 I0 J.5
N413 G01 Y-8.433 F8262.
N414 G03 X19.311 Y-7.995 Z-14.564 I-.439 J0
N415 G01 X17.978 Y-3.766 Z-12.4 F16500.
N416 X17.5 Y-2.25 Z-13.175
N417 G03 X19.75 Y0 Z-14.9 I0 J2.25 F8262.
N418 G01 Y2.41 F4914.44
N419 G03 X12.41 Y9.75 I-7.34 J0
N420 G01 X10. F8262.
N421 G03 X8.736 Y5.638 Z-13.444 I0 J-2.25
N422 G01 X12.134 Y3.332 Z-12.4 F16500.
N423 X16.236 Y.548 Z-13.66
N424 G03 X19.75 Y2.41 Z-14.9 I1.264 J1.862 F8262.
N425 G01 Y4.276
N426 Y4.817 F4103.013
N427 G03 X14.817 Y9.75 I-4.933 J0
N428 G01 X12.41 F8262.
N429 G03 X11.451 Y5.464 Z-12.965 I0 J-2.25
N430 G01 X13.124 Y4.865 Z-12.4 F16500.
N431 X17.405 Y3.33 Z-13.848
N432 G03 X19.75 Y4.817 Z-14.9 I.701 J1.488 F8262.
N433 G01 Y6.023
N434 G03 X16.023 Y9.75 I-3.727 J0 F3528.188
N435 G01 X14.817 F8262.
N436 G03 X14.009 Y6.674 Z-12.965 I0 J-1.644
N437 G01 X15.163 Y6.16 Z-12.4 F16500.
N438 X17.897 Y4.942 Z-13.741
N439 G03 X19.75 Y6.023 Z-14.9 I.61 J1.082 F8262.
N440 G01 Y7.08
N441 Y7.221 F2775.401
N442 G03 X17.221 Y9.75 I-2.529 J0
N443 G01 X16.023 F8262.
N444 G03 X15.517 Y7.373 Z-12.849 I0 J-1.242
N445 G01 X16.225 Y7.159 Z-12.4 F16500.
N446 X18.563 Y6.451 Z-13.882
N447 G03 X19.75 Y7.221 Z-14.9 I.344 J.77 F8262.
N448 G01 Y7.97
N449 Y8.433 F1722.004
N450 G03 X18.433 Y9.75 I-1.317 J0
N451 G01 X17.221 F8262.
N452 G03 X16.383 Y9.001 Z-13.767 I0 J-.843
N453 X17.035 Y8.085 Z-12.634 I.838 J-.094
N454 G01 X17.288 Y8.075 Z-12.4 F16500.
N455 X19.214 Y8.005 Z-14.175
N456 G03 X19.75 Y8.433 Z-14.9 I.097 J.428 F8262.
N457 G01 Y8.844
N458 Y9.25 F1652.4
N459 G03 X19.25 Y9.75 I-.5 J0
N460 G01 X18.433 F8262.
N461 G03 X17.596 Y8.912 Z-12.4 I0 J-.838
N462 G00 Z25. M09
N463 G91 G28 Z0
N464 G28 X0 Y0
N465 M30


`;

// 响应式数据
// const lineCount = ref(0);
// const pointCount = ref(0);
// const moveCount = ref(0);
// const spiralCount = ref(0);
// const gridVisible = ref(true);
// const ncCode = ref('')
const pointsVisible = ref(true);
const axisVisible = ref(true);
const animationSpeed = ref(1); // 动画速度控制变量，默认值1

// 解析NC代码函数(核心)
function parseNCCode(content: string) {
    const lines = content.split('\n');
    const points: { x: number; y: number; z: number; type: string }[] = [];

    // 初始状态
    let currentX = 0;
    let currentY = 0;
    let currentZ = 0;
    let absoluteMode = true;
    let currentMode: string | null = null;
    let localMoveCount = 0;
    let localSpiralCount = 0;
    let currentPlane = 'G17'; // 默认XY平面

    // 起点 (交换y和z坐标)
    points.push({ x: currentX, y: currentZ, z: currentY, type: 'start' });

    for (const line of lines) {
      // 清理行内容（移除行号、注释等）
      let cleanLine = line.replace(/^N\d+\s*/, '').replace(/\(.*?\)/g, '').trim();

      if (!cleanLine) continue;

      const tokens = cleanLine.split(/\s+/);
      let newX: number | null = null;
      let newY: number | null = null;
      let newZ: number | null = null;
      let I: number | null = null;
      let J: number | null = null;
      let K: number | null = null;
      let hasMotion = false;
      let setMode: string | null = null;
      let setAbsolute: boolean | null = null;
      let g28Found = false;
      let setPlane: string | null = null;
      let isSpiral = false;

      for (const token of tokens) {
        if (token.startsWith('G')) {
          const code = token.substring(1);
          if (code === '00' || code === '0') setMode = 'G00';
          else if (code === '01' || code === '1') setMode = 'G01';
          else if (code === '02' || code === '2') setMode = 'G02'; // 顺时针圆弧
          else if (code === '03' || code === '3') setMode = 'G03'; // 逆时针圆弧
          else if (code === '90') setAbsolute = true;
          else if (code === '91') setAbsolute = false;
          else if (code === '28') g28Found = true;
          else if (code === '17') setPlane = 'G17'; // XY平面
          else if (code === '18') setPlane = 'G18'; // ZX平面
          else if (code === '19') setPlane = 'G19'; // YZ平面
        } else if (token.startsWith('X')) {
          newX = parseFloat(token.substring(1));
        } else if (token.startsWith('Y')) {
          newY = parseFloat(token.substring(1));
        } else if (token.startsWith('Z')) {
          newZ = parseFloat(token.substring(1));
        } else if (token.startsWith('I')) {
          I = parseFloat(token.substring(1));
        } else if (token.startsWith('J')) {
          J = parseFloat(token.substring(1));
        } else if (token.startsWith('K')) {
          K = parseFloat(token.substring(1));
        }
      }

      // 处理坐标模式
      if (setAbsolute !== null) {
        absoluteMode = setAbsolute;
      }

      // 处理平面选择
      if (setPlane !== null) {
        currentPlane = setPlane;
      }

      // 处理G28
      if (g28Found) {
        // 对于G28，只将指定的轴设为0，未指定的轴保持不变
        if (newX !== null) newX = 0;
        if (newY !== null) newY = 0;
        if (newZ !== null) newZ = 0;
        hasMotion = true;
        setMode = 'G28';
      }

      // 设置移动模式
      if (setMode !== null) {
        currentMode = setMode;
      }

      // 计算新坐标
      let targetX = currentX;
      let targetY = currentY;
      let targetZ = currentZ;

      if (newX !== null) {
        targetX = absoluteMode ? newX : currentX + newX;
        hasMotion = true;
      }
      if (newY !== null) {
        targetY = absoluteMode ? newY : currentY + newY;
        hasMotion = true;
      }
      if (newZ !== null) {
        targetZ = absoluteMode ? newZ : currentZ + newZ;
        hasMotion = true;
      }

      // 如果有移动，记录点
      if (hasMotion && currentMode) {
        // 螺旋插补检测（圆弧运动+Z轴变化）
        const hasZChange = newZ !== null && Math.abs(targetZ - currentZ) > 0.001;

        // 如果是圆弧运动
        if ((currentMode === 'G02' || currentMode === 'G03') && (I !== null || J !== null || K !== null)) {
          // 检查是否有I,J,K参数
          // 计算圆心（相对起点）
          const centerX = absoluteMode ? currentX + (I || 0) : currentX + (I || 0);
          const centerY = absoluteMode ? currentY + (J || 0) : currentY + (J || 0);
          const centerZ = absoluteMode ? currentZ + (K || 0) : currentZ + (K || 0);

          // 计算起点和终点相对于圆心的向量
          const startVec = {
            x: currentX - centerX,
            y: currentY - centerY,
            z: currentZ - centerZ
          };

          const endVec = {
            x: targetX - centerX,
            y: targetY - centerY,
            z: targetZ - centerZ
          };

          // 计算圆弧角度（弧度）
          let startAngle: number, endAngle: number;
          if (currentPlane === 'G17') {
            // XY平面
            startAngle = Math.atan2(startVec.y, startVec.x);
            endAngle = Math.atan2(endVec.y, endVec.x);
          } else if (currentPlane === 'G18') {
            // ZX平面
            startAngle = Math.atan2(startVec.z, startVec.x);
            endAngle = Math.atan2(endVec.z, endVec.x);
          } else {
            // YZ平面
            startAngle = Math.atan2(startVec.z, startVec.y);
            endAngle = Math.atan2(endVec.z, endVec.y);
          }

          // 调整角度方向
          if (currentMode === 'G03') {
            // 逆时针
            if (endAngle < startAngle) endAngle += Math.PI * 2;
          } else {
            // 顺时针
            if (endAngle > startAngle) endAngle -= Math.PI * 2;
          }

          // 计算圆弧半径
          const radius = Math.sqrt(startVec.x * startVec.x + startVec.y * startVec.y + startVec.z * startVec.z);

          // 插值点数（每10度一个点）
          const segments = Math.max(12, Math.ceil(Math.abs(endAngle - startAngle) * 180 / Math.PI / 10));

          // 生成圆弧上的点
          for (let i = 0; i <= segments; i++) {
            const t = i / segments;
            const angle = startAngle + (endAngle - startAngle) * t;

            let point: { x: number; y: number; z: number } = {} as { x: number; y: number; z: number };
            if (currentPlane === 'G17') {
              // XY平面
              point = {
                x: centerX + Math.cos(angle) * radius,
                y: centerY + Math.sin(angle) * radius,
                z: currentZ + (targetZ - currentZ) * t
              };
            } else if (currentPlane === 'G18') {
              // ZX平面
              point = {
                x: centerX + Math.cos(angle) * radius,
                y: currentY, // Y不变
                z: centerZ + Math.sin(angle) * radius
              };
            } else {
              // YZ平面
              point = {
                x: currentX, // X不变
                y: centerY + Math.cos(angle) * radius,
                z: centerZ + Math.sin(angle) * radius
              };
            }

            // 标记螺旋插补
            const pointType = hasZChange
              ? Math.abs(targetZ - currentZ) > 1
                ? 'helical'
                : 'spiral'
              : currentMode;
            
            // 交换y和z坐标实现翻转
            points.push({ 
              x: point.x, 
              y: point.z,  // 将原始z值赋给y
              z: point.y,  // 将原始y值赋给z
              type: pointType 
            });
          }

          if (hasZChange) {
            localSpiralCount++;
            isSpiral = true;
          }
        } else {
          // 直线移动 - 交换y和z坐标实现翻转
          points.push({ 
            x: targetX, 
            y: targetZ,  // 将原始z值赋给y
            z: targetY,  // 将原始y值赋给z
            type: currentMode 
          });
        }

        currentX = targetX;
        currentY = targetY;
        currentZ = targetZ;
        localMoveCount++;
      }
    }

    return points;
}
let pointCloud: THREE.Points<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.PointsMaterial, THREE.Object3DEventMap> | null = null;
let points: string | any[];
function addPoint() { 
  // 解析NC代码并获取点数组
  points = parseNCCode(ncCode);
  // 创建路径几何体
  const geometry = new THREE.BufferGeometry();
  const material = new THREE.LineBasicMaterial({
    vertexColors: true,
    linewidth: 2
  });

  const vertices: number[] = [];
  const colors: number[] = [];

  // 创建路径点
  const pointGeometry = new THREE.BufferGeometry();
  const pointMaterial = new THREE.PointsMaterial({
    color: 0xffffff,
    size: 2.5,
    sizeAttenuation: false
  });

  const pointPositions: number[] = [];

  for (let i = 0; i < points.length - 1; i++) {
    const p1 = points[i];
    const p2 = points[i + 1];

    // 添加线段
    vertices.push(p1.x, p1.y, p1.z);
    vertices.push(p2.x, p2.y, p2.z);

    // 添加点
    pointPositions.push(p1.x, p1.y, p1.z);

    // 设置颜色
    let color: THREE.Color;
    if (p2.type === 'G00') color = new THREE.Color(1, 0, 0); // 红色
    else if (p2.type === 'G01') color = new THREE.Color(0, 1, 0); // 绿色
    else if (p2.type === 'G02') color = new THREE.Color(0, 0.6, 1); // 蓝色
    else if (p2.type === 'G03') color = new THREE.Color(0.78, 0.49, 1); // 紫色
    else if (p2.type === 'G28') color = new THREE.Color(1, 0.67, 0.2); // 橙色
    else if (p2.type === 'spiral') color = new THREE.Color(1, 0.42, 0.42); // 浅红色
    else if (p2.type === 'helical') color = new THREE.Color(1, 0.82, 0.4); // 黄色
    else color = new THREE.Color(0.7, 0.7, 0.7); // 灰色

    colors.push(color.r, color.g, color.b);
    colors.push(color.r, color.g, color.b);
  }

  // 添加最后一个点
  const lastPoint = points[points.length - 1];
  pointPositions.push(lastPoint.x, lastPoint.y, lastPoint.z);

  geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
  geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

  const path = new THREE.LineSegments(geometry, material);
  scene.add(path);

  // 添加点
  pointGeometry.setAttribute('position', new THREE.Float32BufferAttribute(pointPositions, 3));
  pointCloud = new THREE.Points(pointGeometry, pointMaterial);
  scene.add(pointCloud);
}

// 添加深度指示器
const depthIndicator = document.getElementById('depthValue');
// 使用Tween重构路径动画
let animPoint: THREE.Mesh | null = null;
let currentAnimation: TWEEN.Tween | null = null;

// 播放路径动画
const playPathAnimation = () => {
  // 停止当前动画
  stopAnimation();
  
  // 创建动画点
  const animGeometry = new THREE.SphereGeometry(0.3, 16, 16);
  const animMaterial = new THREE.MeshBasicMaterial({
    color: 0xff0000,
    depthTest: false
  });
  
  animPoint = new THREE.Mesh(animGeometry, animMaterial);
  animPoint.renderOrder = 999;
  scene.add(animPoint);
  
  // 设置动画点初始位置
  animPoint.position.copy(new THREE.Vector3(
    points[0].x, 
    points[0].y, 
    points[0].z
  ));
  
  // 添加光源到动画点
  const pointLight = new THREE.PointLight(0xff0000, 2, 20);
  animPoint.add(pointLight);
  
  // 动画参数 - 使用animationSpeed控制速度
  const baseSpeed = 100; // 基础速度
  const actualSpeed = baseSpeed * animationSpeed.value; // 计算实际速度
  
  let currentIndex = 0;
  
  // 递归播放每段动画
  function playNextSegment() {
    if (currentIndex >= points.length - 1) {
      // 动画结束
      scene.remove(animPoint!);
      animPoint = null;
      return;
    }
    
    const startPoint = points[currentIndex];
    const endPoint = points[currentIndex + 1];
    
    // 计算两点间距离和所需时间
    const distance = Math.sqrt(
      Math.pow(endPoint.x - startPoint.x, 2) +
      Math.pow(endPoint.y - startPoint.y, 2) +
      Math.pow(endPoint.z - startPoint.z, 2)
    );
    
    // 使用actualSpeed计算持续时间
    const duration = (distance / actualSpeed) * 1000; // 毫秒
    
    // 创建Tween动画
    currentAnimation = new TWEEN.Tween(animPoint!.position)
      .to({
        x: endPoint.x,
        y: endPoint.y,
        z: endPoint.z
      }, duration)
      .easing(TWEEN.Easing.Linear.None)
      .onUpdate(() => {
        // 更新深度指示器
        if (depthIndicator) {
          depthIndicator.textContent = 
            Math.abs(animPoint!.position.z).toFixed(2) + ' mm';
        }
      })
      .onComplete(() => {
        currentIndex++;
        playNextSegment();
      })
      .start();
  }
  
  playNextSegment();
}
  
// 停止路径动画
function stopAnimation() {
  if (currentAnimation) {
    currentAnimation.stop();
    currentAnimation = null;
  }
  
  if (animPoint) {
    scene.remove(animPoint);
    animPoint = null;
  }
  
  // 重置深度指示器
  if (depthIndicator) depthIndicator.textContent = '0.00 mm';
}

// 显示路径点信息
const showPointInfo = () => { 
  
   // 鼠标悬停显示工具提示
   const tooltip = document.getElementById('tooltip');
  const tooltipX = document.getElementById('tooltipX');
  const tooltipY = document.getElementById('tooltipY');
  const tooltipZ = document.getElementById('tooltipZ');
  const tooltipType = document.getElementById('tooltipType');
  const tooltipIndex = document.getElementById('tooltipIndex');
  const tooltipDepth = document.getElementById('tooltipDepth');

  const raycaster = new THREE.Raycaster();
  const mouse = new THREE.Vector2();

  function onMouseMove(event: MouseEvent) {
    // 计算鼠标位置
    const rect = render.domElement.getBoundingClientRect();
    mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

    // 更新射线
    raycaster.setFromCamera(mouse, camera);

    // 检测与路径点的交点
    const intersects = raycaster.intersectObject(pointCloud);

    if (intersects.length > 0) {
      const intersect = intersects[0];
      const index = Math.floor(intersect.index); // 每个点有3个值

      if (index >= 0 && index < points.length) {
        const point = points[index];

        // 更新工具提示内容
        if (tooltipX) tooltipX.textContent = point.x.toFixed(3);
        if (tooltipY) tooltipY.textContent = point.y.toFixed(3);
        if (tooltipZ) tooltipZ.textContent = point.z.toFixed(3);

        let typeName = point.type;
        if (typeName === 'G00') typeName = '快速移动';
        else if (typeName === 'G01') typeName = '直线进给';
        else if (typeName === 'G02') typeName = '顺时针圆弧';
        else if (typeName === 'G03') typeName = '逆时针圆弧';
        else if (typeName === 'spiral') typeName = '螺旋插补';
        else if (typeName === 'helical') typeName = '螺旋下刀';
        else if (typeName === 'G28') typeName = '回零操作';

        if (tooltipType) tooltipType.textContent = typeName;
        if (tooltipIndex) tooltipIndex.textContent = index.toString();
        if (tooltipDepth) tooltipDepth.textContent = Math.abs(point.z).toFixed(2);

        // 更新深度指示器
        if (depthIndicator) depthIndicator.textContent = Math.abs(point.z).toFixed(2) + ' mm';

        // 显示工具提示
        if (tooltip) {
          tooltip.style.display = 'block';
          tooltip.style.left = event.pageX + 15 + 'px';
          tooltip.style.top = event.pageY + 15 + 'px';
        }

        return;
      }
    }

    // 没有交点时隐藏工具提示
    if (tooltip) tooltip.style.display = 'none';
  }
  // document.getElementById('visualization')!.addEventListener('mousemove', onMouseMove);
  clear.value.addEventListener('mousemove', onMouseMove);
  // 初始显示深度
  if (depthIndicator) depthIndicator.textContent = '0.00 mm';
};

// 重置视图
const resetView = () => { 
  camera.position.set(0, 100, 150);
    camera.lookAt(0, 0, 0);
    controls.reset();
};

// 切换路径点是否显示
const togglePoints = () => {
  pointsVisible.value = !pointsVisible.value;
  pointCloud.visible = pointsVisible.value;
};

// 切换坐标轴是否显示
const toggleAxis = () => { 
  axisVisible.value = !axisVisible.value;
  axesHelper.visible = axisVisible.value;
};

onMounted(() => {
  clear.value.appendChild(render.domElement);
  animate();
  addPoint();
  showPointInfo();
});

// 组件卸载时停止动画
onUnmounted(() => {
  stopAnimation();
});
</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

body {
  background: linear-gradient(135deg, #1a2a6c, #2c3e50);
  color: #fff;
  min-height: 100vh;
  overflow-x: hidden;
}

.container {
  display: flex;
  flex-direction: column;
  max-width: 1800px;
  margin: 0 auto;
  padding: 20px;
  height: 100vh;
}

header {
  text-align: center;
  padding: 20px 0;
  margin-bottom: 20px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

h1 {
  font-size: 2.8rem;
  margin-bottom: 10px;
  background: linear-gradient(90deg, #4facfe, #00f2fe);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

.subtitle {
  color: #a0d2ff;
  font-size: 1.2rem;
  max-width: 1000px;
  margin: 0 auto;
  line-height: 1.7;
}

.content {
  display: flex;
  flex: 1;
  gap: 30px;
  height: calc(100% - 160px);
}

.panel {
  background: rgba(25, 40, 65, 0.85);
  border-radius: 18px;
  padding: 25px;
  box-shadow: 0 12px 35px rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(100, 180, 255, 0.2);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
}

.panel:hover {
  box-shadow: 0 15px 40px rgba(0, 0, 0, 0.5);
  transform: translateY(-5px);
}

.code-panel {
  flex: 1;
  min-width: 450px;
}

.visualization-panel {
  /* flex: 2; */
  width: 1000px;
}

#visualization{
  width: 1000px;
  height: 600px;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 25px;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

h2 {
  font-size: 1.7rem;
  color: #4facfe;
  display: flex;
  align-items: center;
  gap: 12px;
}

.icon {
  font-size: 1.4rem;
}

.file-info {
  background: rgba(10, 25, 50, 0.6);
  padding: 8px 15px;
  border-radius: 8px;
  font-size: 0.95rem;
}

.code-container {
  background: rgba(10, 20, 40, 0.65);
  border-radius: 12px;
  padding: 18px;
  height: calc(100% - 80px);
  overflow-y: auto;
  font-family: 'Courier New', monospace;
  font-size: 1.05rem;
  line-height: 1.7;
  white-space: pre;
  color: #e2e8f0;
  box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.6);
}

#visualization {
  width: 100%;
  height: calc(100% - 70px);
  border-radius: 12px;
  overflow: hidden;
  background: #0a1424;
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.8);
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 18px;
  justify-content: center;
  padding: 10px;
  background: #fff;
  border-radius: 10px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.95rem;
}

.legend-color {
  width: 22px;
  height: 5px;
  border-radius: 3px;
}

.g00 {
  background: #ff4d4d;
}
.g01 {
  background: #4dff88;
}
.g02 {
  background: #4d9dff;
}
.g03 {
  background: #c77dff;
}
.g28 {
  background: #ffaa33;
}
.spiral {
  background: #ff6b6b;
}
.helical {
  background: #ffd166;
}
.other {
  background: #aaaaaa;
}
.anim {
  background: #ff0000;
}

.stats {
  display: flex;
  justify-content: space-around;
  background: rgba(10, 25, 50, 0.7);
  border-radius: 12px;
  padding: 15px;
  margin-top: 20px;
  font-size: 1rem;
}

.stat {
  text-align: center;
  padding: 0 15px;
}

.stat-title {
  font-size: 1rem;
  color: #a0d2ff;
  margin-bottom: 5px;
}

.stat-value {
  font-size: 1.6rem;
  font-weight: bold;
  color: #00f2fe;
}

.highlight {
  background: rgba(79, 172, 254, 0.35);
  color: #fff;
  padding: 3px 6px;
  border-radius: 4px;
}

.tooltip {
  position: absolute;
  background: rgba(25, 40, 65, 0.97);
  border: 1px solid rgba(100, 200, 255, 0.6);
  border-radius: 8px;
  padding: 15px;
  color: white;
  font-size: 15px;
  pointer-events: none;
  z-index: 100;
  min-width: 240px;
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(5px);
}

.tooltip h3 {
  margin-bottom: 10px;
  color: #4facfe;
  border-bottom: 1px solid rgba(255, 255, 255, 0.25);
  padding-bottom: 8px;
}

.tooltip p {
  margin: 8px 0;
  display: flex;
  justify-content: space-between;
}

.tooltip .value {
  color: #00f2fe;
  font-weight: bold;
}

.controls {
  display: flex;
  gap: 15px;
  margin-top: 20px;
  justify-content: center;
  flex-wrap: wrap;
}

.speed-control{
  display: flex;
}


button {
  background: linear-gradient(to right, #4facfe, #00f2fe);
  color: #0a1424;
  border: none;
  border-radius: 8px;
  padding: 10px 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: bold;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}

button:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 15px rgba(0, 0, 0, 0.4);
}

.toggle-btn {
  background: rgba(79, 172, 254, 0.25);
  color: white;
}

@media (max-width: 1400px) {
  .content {
    flex-direction: column;
  }

  .code-panel,
  .visualization-panel {
    min-width: unset;
  }

  .legend {
    gap: 12px;
  }
}

@media (max-width: 768px) {
  h1 {
    font-size: 2.2rem;
  }

  .subtitle {
    font-size: 1rem;
  }

  .controls {
    gap: 10px;
  }

  button {
    padding: 8px 15px;
    font-size: 0.9rem;
  }
}

.depth-indicator {
  position: absolute;
  top: 20px;
  right: 20px;
  background: rgba(25, 40, 65, 0.85);
  padding: 15px;
  border-radius: 10px;
  z-index: 10;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

.depth-title {
  color: #4facfe;
  font-weight: bold;
  margin-bottom: 8px;
}

.depth-value {
  font-size: 1.8rem;
  color: #00f2fe;
  font-weight: bold;
  text-align: center;
}

.animation-info {
  position: absolute;
  top: 20px;
  left: 20px;
  background: rgba(25, 40, 65, 0.85);
  padding: 15px;
  border-radius: 10px;
  z-index: 10;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

.animation-title {
  color: #4facfe;
  font-weight: bold;
  margin-bottom: 8px;
}

.animation-value {
  font-size: 1.2rem;
  color: #00f2fe;
  text-align: center;
}
</style>